package cn.iocoder.yudao.module.student.service.student;

import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.member.api.appAuth.AppAuthApi;
import cn.iocoder.yudao.module.member.api.banner.dto.AppAuthLoginReqDTO;
import cn.iocoder.yudao.module.member.api.studentCurriculumVitae.StudentCurriculumVitaeApi;
import cn.iocoder.yudao.module.member.api.studentCurriculumVitae.dto.StudentCurriculumVitaeUpdateReqDTO;
import cn.iocoder.yudao.module.student.controller.app.student.vo.*;
import cn.iocoder.yudao.module.student.convert.student.WebStudentConvert;
import cn.iocoder.yudao.module.student.dal.dataobject.student.WebStudentDO;
import cn.iocoder.yudao.module.student.dal.mysql.student.WebStudentMapper;
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
import static cn.iocoder.yudao.module.student.enums.ErrorCodeConstants.WEB_STUDENT_NEW_PHONE_IS_EXISTS;
import static cn.iocoder.yudao.module.student.enums.ErrorCodeConstants.WEB_STUDENT_NOT_EXISTS;
/**
 * 学生管理 Service 实现类
 *
 * @author 周枫皓
 */
@Service
@Validated
public class WebStudentServiceImpl implements WebStudentService {

    @Resource
    private WebStudentMapper webStudentMapper;
    @Resource
    private AppAuthApi appAuthApi;
    @Resource
    private SmsCodeApi smsCodeApi;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private StudentCurriculumVitaeApi studentCurriculumVitaeApi;

    @Override
    public Long createWebStudent(WebStudentCreateReqVO createReqVO) {
        // 插入

        WebStudentDO webStudent=webStudentMapper.selectOne("mobile",createReqVO.getMobile());
        if(webStudent==null){
            webStudent = WebStudentConvert.INSTANCE.convert(createReqVO);
            webStudentMapper.insert(webStudent);
        }else {
            webStudentMapper.updateById(webStudent);
        }
        // 返回
        return webStudent.getId();
    }

    @Override
    public void updateWebStudent(WebStudentUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateWebStudentExists(updateReqVO.getId());
        // 更新
        WebStudentDO updateObj = WebStudentConvert.INSTANCE.convert(updateReqVO);
        updateObj.setPostDate(new Date());
        webStudentMapper.updateById(updateObj);
        StudentCurriculumVitaeUpdateReqDTO updateReqDTO=new StudentCurriculumVitaeUpdateReqDTO();
        updateReqDTO.setStudentId(updateReqVO.getId());
        updateReqDTO.setStudentName(updateReqVO.getStudentName());
        updateReqDTO.setSex(updateReqVO.getSex());
        updateReqDTO.setBirthday(updateReqVO.getBirthday());
        updateReqDTO.setClan(updateReqVO.getClan());
        updateReqDTO.setPolitical(updateReqVO.getPolitical());
        updateReqDTO.setNativePlace(updateReqVO.getNativePlace());
        updateReqDTO.setIdentify(updateReqVO.getIdentify());
        updateReqDTO.setLiveCity(updateReqVO.getLiveCity());
        updateReqDTO.setEmail(updateReqVO.getEmail());
        studentCurriculumVitaeApi.updateByStudentId(updateReqDTO);

    }

    @Override
    public void deleteWebStudent(Long id) {
        // 校验存在
        this.validateWebStudentExists(id);
        // 删除
        webStudentMapper.deleteById(id);
    }

    private void validateWebStudentExists(Long id) {
        if (webStudentMapper.selectById(id) == null) {
            throw exception(WEB_STUDENT_NOT_EXISTS);
        }
    }

    @Override
    public WebStudentDO getWebStudent(Long id) {
        return webStudentMapper.selectById(id);
    }

    @Override
    public WebStudentDO getWebStudent(String mobile) {
        return webStudentMapper.selectOne("mobile",mobile);
    }

    @Override
    public List<WebStudentDO> getWebStudentList(Collection<Long> ids) {
        return webStudentMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<WebStudentDO> getWebStudentPage(WebStudentPageReqVO pageReqVO) {
        return webStudentMapper.selectPage(pageReqVO);
    }

    @Override
    public List<WebStudentDO> getWebStudentList(WebStudentExportReqVO exportReqVO) {
        return webStudentMapper.selectList(exportReqVO);
    }

    private final String accessTokenKey="wechat_access_token";
    public String getAccessToken() {
        String accessToken = stringRedisTemplate.opsForValue().get(accessTokenKey);
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        stringRedisTemplate.opsForValue().set(accessTokenKey,accessToken,1,TimeUnit.HOURS  );
    }

    @Override
    public String getWechatPhone(@Valid @RequestBody WechartTokenReqVo createReqVO) {
        String accessToken = getAccessToken();
        if (StringUtils.isBlank(accessToken)) {
            String tokenStr = HttpUtils.doGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxa1b7157da4197ce2&secret=60abc4dab6d22ae1a6873cb9f988e1a4");
            WechartTokenResVo wechartTokenResVo = JsonUtils.parseObject(tokenStr, WechartTokenResVo.class);
            if (wechartTokenResVo.getErrcode() == null || wechartTokenResVo.getErrcode().equals("0")) {
                accessToken = wechartTokenResVo.getAccess_token();
                setAccessToken(accessToken);
            }
        }
        Assert.notBlank(accessToken, "获取微信信息失败,请重新登录");
        Map<String, Object> res = new HashMap<>();
        Map<String, String> code = new HashMap<>();
        code.put("code", createReqVO.getCode());
        String phoneStr = HttpUtils.doPost("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken + "&", JsonUtils.toJsonString(code));
        WechartPhoneResVo wechartPhoneResVo = JsonUtils.parseObject(phoneStr, WechartPhoneResVo.class);
        if (wechartPhoneResVo.getErrcode() == null || wechartPhoneResVo.getErrcode().equals("0")) {
            Phoneinfo phone_info = wechartPhoneResVo.getPhone_info();
            AppAuthLoginReqDTO appAuthLoginReqDTO = new AppAuthLoginReqDTO();
            appAuthLoginReqDTO.setMobile(phone_info.getPhoneNumber());
            String loginToken = appAuthApi.login(appAuthLoginReqDTO);
            res.put("phoneNumber", phone_info.getPhoneNumber());
            res.put("loginToken", loginToken);
            return JsonUtils.toJsonString(res);
        }
        return null;
    }

    @Override
    public Boolean changeStudentPhone(WebStudentUpdatePhoneReqVO updateReqVO) {
        SmsCodeUseReqDTO smsCodeUseReqDTO=new SmsCodeUseReqDTO();
        smsCodeUseReqDTO.setMobile(updateReqVO.getNewMobile());
        smsCodeUseReqDTO.setScene(updateReqVO.getScene());
        smsCodeUseReqDTO.setCode(updateReqVO.getCode());
        smsCodeUseReqDTO.setUsedIp(getClientIP());
        smsCodeApi.useSmsCode(smsCodeUseReqDTO);
        updateReqVO.setUsedIp(getClientIP());
        WebStudentDO studentDO=webStudentMapper.selectOne("mobile",updateReqVO.getOldMobile());
        WebStudentDO newStudentDO=webStudentMapper.selectOne("mobile",updateReqVO.getNewMobile());
        if (newStudentDO != null) {
            throw exception(WEB_STUDENT_NEW_PHONE_IS_EXISTS);
        }
        if(studentDO!=null){
            studentDO.setMobile(updateReqVO.getNewMobile());
            webStudentMapper.updateById(studentDO);
        }else{
            throw exception(WEB_STUDENT_NOT_EXISTS);
        }

        return true;
    }

    @Override
    public Boolean updateIsRealName(WebStudentUpdateReqVO updateReqVO) {
        WebStudentDO updateObj = WebStudentConvert.INSTANCE.convert(updateReqVO);
        webStudentMapper.updateById(updateObj);
        return true;
    }

    @Override
    public List<WebStudentInfoRespVO> getStudentInfoList(Integer pageNo,Integer pageSize) {
        List<WebStudentInfoRespVO> studentInfoList1 = webStudentMapper.getStudentInfoList1(pageNo,  pageSize);
        return studentInfoList1;
    }

    @Override
    public long getCountByMobile(String mobile) {
        Long n = webStudentMapper.selectCount("mobile", mobile);
        return null==n ? 0 : n;
    }
}
